using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

namespace Nirvana
{
    public enum ObjectType
    {
        /// <summary>
        /// 节点
        /// </summary>
        Node,

        /// <summary>
        /// 静态Mesh
        /// </summary>
        Mesh,

        /// <summary>
        /// 地形
        /// </summary>
        Terrain,

        /// <summary>
        /// 灯光
        /// </summary>
        Light,

        /// <summary>
        /// 动画
        /// </summary>
        Animator,

        /// <summary>
        /// 静态Group节点
        /// </summary>
        GroupNode,

        /// <summary>
        /// 静态GroupMesh
        /// </summary>
        GroupMesh,

        /// <summary>
        /// 以Prefab形式进行加载
        /// </summary>
        Prefab,

        /// <summary>
        /// 以Prefab形式进行加载，会被外部调用
        /// </summary>
        DynamicPrefab
    }

    public class SerializedGameObject : IBigWorldIO, IBigWorldLoad, IBigWorldUpdate, IBigWorldClear
    {
        /// <summary>
        /// 类型
        /// </summary>
        public ObjectType Type;

        /// <summary>
        /// 名称
        /// </summary>
        public string Name;

        /// <summary>
        /// 父节点Id
        /// </summary>
        public int ParentId;

        /// <summary>
        /// 层级
        /// </summary>
        public int Layer;

        /// <summary>
        /// 世界位置
        /// </summary>
        public Vector3 Position;

        /// <summary>
        /// 本地位置
        /// </summary>
        public Vector3 LocalPosition;

        /// <summary>
        /// 本地欧拉角
        /// </summary>
        public Vector3 LocalEulerAngles;

        /// <summary>
        /// 本地缩放
        /// </summary>
        public Vector3 LocalScale;

        /// <summary>
        /// 父节点
        /// </summary>
        public Transform Parent;

        /// <summary>
        /// 节点
        /// </summary>
        public Transform Node;

        protected BigWorld.GetResPath GetResPathFunc;

        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="parent">父节点</param>
        /// <param name="node">此节点</param>
        public virtual void Init(Transform parent, Transform node, BigWorld.GetResPath func)
        {
            Parent = parent;
            if (node != null)
            {
                Node = node;
                node.SetParent(parent);
                node.gameObject.layer = Layer;
                node.transform.localPosition = LocalPosition;
                node.transform.localEulerAngles = LocalEulerAngles;
                node.transform.localScale = LocalScale;
            }

            GetResPathFunc = func;
        }

        public void NodeToDeserialize(int parentId, Transform node, ObjectType type)
        {
            Type = type;
            Name = node.gameObject.name;
            ParentId = parentId;
            Layer = node.gameObject.layer;
            Position = node.position;
            LocalPosition = node.transform.localPosition;
            LocalEulerAngles = node.transform.localEulerAngles;
            LocalScale = node.transform.localScale;
        }

        public virtual void Update()
        {
        }

        public virtual void Load()
        {
        }

        public virtual void UnLoad()
        {
        }

        protected virtual void OnClear()
        {
        }

        public void Clear()
        {
            UnLoad();
            Parent = null;
            Node = null;
            OnClear();
        }

        protected virtual void OnWrite(BinaryWriter writer)
        {
        }

        protected virtual void OnRead(BinaryReader reader)
        {
        }

        public void Write(BinaryWriter writer)
        {
            writer.Write((int) Type);
            writer.Write(Name);
            writer.Write(ParentId);
            writer.Write(Layer);
            writer.Write(Position);
            writer.Write(LocalPosition);
            writer.Write(LocalEulerAngles);
            writer.Write(LocalScale);
            OnWrite(writer);
        }

        public void Read(BinaryReader reader)
        {
            // 外部读取Type来生成具体实例对象
            // Type = (ObjectType) reader.ReadInt32();
            Name = reader.ReadString();
            ParentId = reader.ReadInt32();
            Layer = reader.ReadInt32();
            Position = reader.ReadVector3();
            LocalPosition = reader.ReadVector3();
            LocalEulerAngles = reader.ReadVector3();
            LocalScale = reader.ReadVector3();
            OnRead(reader);
        }
    }
}